package com.diy.sigmund.diycommon.util.reflect;

import com.diy.sigmund.diycommon.spring.CustomApplicationContext;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 利用反射处理的工具类
 *
 * @author ylm-sigmund
 * @since 2021/5/9 8:45
 */
public class ReflectUtil {

    /**
     * 日志
     */
    private static final Logger log = LoggerFactory.getLogger(ReflectUtil.class);

    /**
     * 比较两个实体属性值，返回属性差异比较结果，逗号分隔
     *
     * @param obj1        进行属性比较的对象1
     * @param obj2        进行属性比较的对象2
     * @param compareList 选择要比较的属性集合
     * @return String 属性差异比较结果，逗号分隔
     */
    public static String compareFields(Object obj1, Object obj2, List<String> compareList) {
        if (Objects.isNull(obj1) || Objects.isNull(obj2)) {
            return null;
        }
        if (CollectionUtils.isEmpty(compareList)) {
            return null;
        }
        // 只有两个对象都是同一类型的才有可比性
        if (obj1.getClass() != obj2.getClass()) {
            return null;
        }
        final StringBuilder sb = new StringBuilder();
        try {
            Class clazz = obj1.getClass();
            // 返回bean的所有属性的描述符
            PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz, Object.class).getPropertyDescriptors();
            // 这里就是所有的属性
            for (PropertyDescriptor pd : pds) {
                // 属性名
                String name = pd.getName();
                // 当前属性选择进行比较
                if (compareList.contains(name)) {
                    // get方法
                    Method readMethod = pd.getReadMethod();
                    // 在obj1上调用get方法等同于获得obj1的属性值
                    Object objValue1 = readMethod.invoke(obj1);
                    // 在obj2上调用get方法等同于获得obj2的属性值
                    Object objValue2 = readMethod.invoke(obj2);
                    if (!Objects.equals(objValue1, objValue2)) {
                        sb.append(name).append(",");
                    }
                }
            }
            return sb.toString();
        } catch (Exception e) {
            log.error("compareFields error", e);
            return null;
        }
    }

    public void setField() {
        Class<?> redissonClient = CustomApplicationContext.getApplicationContext().getType("redissonClient");
        Object redissonClient1 = CustomApplicationContext.getBean("redissonClient");
        Field[] declaredFields = redissonClient.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            String name = declaredField.getName();
            System.out.println(name);
            declaredField.setAccessible(true);
            try {
                if (Objects.equals(name, "connectionManager")) {
                    declaredField.set(redissonClient1, new Object());
                }
                if (Objects.equals(name, "commandExecutor")) {
                    declaredField.set(redissonClient1, new Object());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

        }
    }

}
